package handlers

import (
	"backEnd/database"
	"backEnd/models"
	"backEnd/utils"
	"database/sql"
	"net/http"
	"strconv"
	"time"

	"github.com/gin-gonic/gin"
)

// GetWallList 获取分类中壁纸列表
func GetWallList(c *gin.Context) {
	startTime := time.Now()

	classID := c.Query("classid")
	if classID == "" {
		c.JSON(http.StatusOK, models.Response{
			ErrCode:  400,
			ErrMsg:   "分类ID不能为空",
			Data:     nil,
			TimeCost: time.Since(startTime).Milliseconds(),
		})
		return
	}

	pageNum, _ := strconv.Atoi(c.DefaultQuery("pageNum", "1"))
	pageSize, _ := strconv.Atoi(c.DefaultQuery("pageSize", "9"))
	offset := (pageNum - 1) * pageSize

	query := `
		SELECT w.id, w.classid, w.description, w.small_picurl, w.score, w.nickname,
		       GROUP_CONCAT(wt.tag_name ORDER BY wt.tag_name SEPARATOR ',') as tags
		FROM wallpaper w
		LEFT JOIN wallpaper_tag wt ON w.id = wt.wallpaper_id
		WHERE w.classid = ? AND w.checked = 1
		GROUP BY w.id, w.classid, w.description, w.small_picurl, w.score, w.nickname
		ORDER BY w.create_time DESC
		LIMIT ? OFFSET ?
	`

	rows, err := database.DB.Query(query, classID, pageSize, offset)
	if err != nil {
		c.JSON(http.StatusOK, models.Response{
			ErrCode:  400,
			ErrMsg:   "查询失败",
			Data:     nil,
			TimeCost: time.Since(startTime).Milliseconds(),
		})
		return
	}
	defer rows.Close()

	var wallpapers []models.Wallpaper
	for rows.Next() {
		var wallpaper models.Wallpaper
		var tabsStr sql.NullString
		var score sql.NullFloat64

		err := rows.Scan(&wallpaper.ID, &wallpaper.ClassID, &wallpaper.Description, &wallpaper.SmallPicURL, &score, &wallpaper.Nickname, &tabsStr)
		if err != nil {
			continue
		}

		if score.Valid {
			wallpaper.Score = utils.FormatFloat(score.Float64)
		} else {
			wallpaper.Score = "0"
		}

		if tabsStr.Valid {
			wallpaper.Tabs = utils.ParseTabsString(tabsStr.String)
		} else {
			wallpaper.Tabs = []string{}
		}

		wallpapers = append(wallpapers, wallpaper)
	}

	// 获取总数
	var total int
	countQuery := "SELECT COUNT(*) FROM wallpaper WHERE classid = ? AND checked = 1"
	database.DB.QueryRow(countQuery, classID).Scan(&total)

	c.JSON(http.StatusOK, models.Response{
		ErrCode:  0,
		ErrMsg:   "查询成功",
		Data:     wallpapers,
		Total:    &total,
		TimeCost: time.Since(startTime).Milliseconds(),
	})
}

// GetRandomWall 获取随机9张壁纸
func GetRandomWall(c *gin.Context) {
	startTime := time.Now()

	query := `
		SELECT w.id, w.classid, w.description, w.small_picurl, w.score, w.nickname,
		       GROUP_CONCAT(wt.tag_name ORDER BY wt.tag_name SEPARATOR ',') as tags
		FROM wallpaper w
		LEFT JOIN wallpaper_tag wt ON w.id = wt.wallpaper_id
		WHERE w.checked = 1
		GROUP BY w.id, w.classid, w.description, w.small_picurl, w.score, w.nickname
		ORDER BY RAND()
		LIMIT 9
	`

	rows, err := database.DB.Query(query)
	if err != nil {
		c.JSON(http.StatusOK, models.Response{
			ErrCode:  400,
			ErrMsg:   "查询失败",
			Data:     nil,
			TimeCost: time.Since(startTime).Milliseconds(),
		})
		return
	}
	defer rows.Close()

	var wallpapers []models.Wallpaper
	for rows.Next() {
		var wallpaper models.Wallpaper
		var tabsStr sql.NullString
		var score sql.NullFloat64

		err := rows.Scan(&wallpaper.ID, &wallpaper.ClassID, &wallpaper.Description, &wallpaper.SmallPicURL, &score, &wallpaper.Nickname, &tabsStr)
		if err != nil {
			continue
		}

		if score.Valid {
			wallpaper.Score = utils.FormatFloat(score.Float64)
		} else {
			wallpaper.Score = "0"
		}

		if tabsStr.Valid {
			wallpaper.Tabs = utils.ParseTabsString(tabsStr.String)
		} else {
			wallpaper.Tabs = []string{}
		}

		wallpapers = append(wallpapers, wallpaper)
	}

	c.JSON(http.StatusOK, models.Response{
		ErrCode:  0,
		ErrMsg:   "查询成功",
		Data:     wallpapers,
		TimeCost: time.Since(startTime).Milliseconds(),
	})
}

// GetDetailWall 获取单个壁纸详情
func GetDetailWall(c *gin.Context) {
	startTime := time.Now()

	wallID := c.Query("id")
	if wallID == "" {
		c.JSON(http.StatusOK, models.Response{
			ErrCode:  400,
			ErrMsg:   "壁纸ID不能为空",
			Data:     nil,
			TimeCost: time.Since(startTime).Milliseconds(),
		})
		return
	}

	query := `
		SELECT w.id, w.classid, w.description, w.small_picurl, w.score, w.nickname,
		       GROUP_CONCAT(wt.tag_name ORDER BY wt.tag_name SEPARATOR ',') as tags
		FROM wallpaper w
		LEFT JOIN wallpaper_tag wt ON w.id = wt.wallpaper_id
		WHERE w.id = ?
		GROUP BY w.id, w.classid, w.description, w.small_picurl, w.score, w.nickname
	`

	var wallpaper models.Wallpaper
	var tabsStr sql.NullString
	var score sql.NullFloat64

	err := database.DB.QueryRow(query, wallID).Scan(&wallpaper.ID, &wallpaper.ClassID, &wallpaper.Description, &wallpaper.SmallPicURL, &score, &wallpaper.Nickname, &tabsStr)
	if err != nil {
		c.JSON(http.StatusOK, models.Response{
			ErrCode:  400,
			ErrMsg:   "查询失败",
			Data:     nil,
			TimeCost: time.Since(startTime).Milliseconds(),
		})
		return
	}

	if score.Valid {
		wallpaper.Score = utils.FormatFloat(score.Float64)
	} else {
		wallpaper.Score = "0"
	}

	if tabsStr.Valid {
		wallpaper.Tabs = utils.ParseTabsString(tabsStr.String)
	} else {
		wallpaper.Tabs = []string{}
	}

	c.JSON(http.StatusOK, models.Response{
		ErrCode:  0,
		ErrMsg:   "查询成功",
		Data:     []models.Wallpaper{wallpaper},
		TimeCost: time.Since(startTime).Milliseconds(),
	})
}

// SetupScore 为壁纸评分
func SetupScore(c *gin.Context) {
	startTime := time.Now()

	accessKey := c.GetString("access_key")
	classID := c.Query("classid")
	wallID := c.Query("wallId")
	userScoreStr := c.Query("userScore")

	if classID == "" || wallID == "" || userScoreStr == "" {
		c.JSON(http.StatusOK, models.Response{
			ErrCode:  400,
			ErrMsg:   "参数不完整",
			Data:     nil,
			TimeCost: time.Since(startTime).Milliseconds(),
		})
		return
	}

	userScore, err := utils.StringToFloat(userScoreStr)
	if err != nil {
		c.JSON(http.StatusOK, models.Response{
			ErrCode:  400,
			ErrMsg:   "评分格式错误",
			Data:     nil,
			TimeCost: time.Since(startTime).Milliseconds(),
		})
		return
	}

	// 生成ID
	scoreID := utils.GenerateID()
	createTime := utils.GetCurrentTimestamp()

	// 插入或更新评分记录
	insertQuery := `
		INSERT INTO user_score (id, access_key, wallpaper_id, classid, user_score, create_time)
		VALUES (?, ?, ?, ?, ?, ?)
		ON DUPLICATE KEY UPDATE user_score = ?, create_time = ?
	`

	_, err = database.DB.Exec(insertQuery, scoreID, accessKey, wallID, classID, userScore, createTime, userScore, createTime)
	if err != nil {
		c.JSON(http.StatusOK, models.Response{
			ErrCode:  400,
			ErrMsg:   "评分失败",
			Data:     nil,
			TimeCost: time.Since(startTime).Milliseconds(),
		})
		return
	}

	// 更新壁纸的平均分
	updateScoreQuery := `
		UPDATE wallpaper 
		SET score = (
			SELECT AVG(user_score) 
			FROM user_score 
			WHERE wallpaper_id = ?
		)
		WHERE id = ?
	`
	database.DB.Exec(updateScoreQuery, wallID, wallID)

	c.JSON(http.StatusOK, models.Response{
		ErrCode:  0,
		ErrMsg:   "新增成功",
		Data:     gin.H{"id": scoreID},
		TimeCost: time.Since(startTime).Milliseconds(),
	})
}

// DownloadWall 壁纸下载
func DownloadWall(c *gin.Context) {
	startTime := time.Now()

	accessKey := c.GetString("access_key")
	classID := c.Query("classid")
	wallID := c.Query("wallId")

	if classID == "" || wallID == "" {
		c.JSON(http.StatusOK, models.Response{
			ErrCode:  400,
			ErrMsg:   "参数不完整",
			Data:     nil,
			TimeCost: time.Since(startTime).Milliseconds(),
		})
		return
	}

	// 生成ID
	downloadID := utils.GenerateID()
	createTime := utils.GetCurrentTimestamp()

	// 插入下载记录
	insertQuery := `
		INSERT INTO user_download (id, access_key, wallpaper_id, classid, create_time)
		VALUES (?, ?, ?, ?, ?)
	`
	_, err := database.DB.Exec(insertQuery, downloadID, accessKey, wallID, classID, createTime)
	if err != nil {
		c.JSON(http.StatusOK, models.Response{
			ErrCode:  400,
			ErrMsg:   "下载失败",
			Data:     nil,
			TimeCost: time.Since(startTime).Milliseconds(),
		})
		return
	}

	c.JSON(http.StatusOK, models.Response{
		ErrCode:  0,
		ErrMsg:   "下载成功",
		Data:     gin.H{"id": downloadID},
		TimeCost: time.Since(startTime).Milliseconds(),
	})
}

// GetUpToDate 获取近期更新的壁纸列表
func GetUpToDate(c *gin.Context) {
	startTime := time.Now()
	accessKey := c.GetString("access_key")

	pageNum, _ := strconv.Atoi(c.DefaultQuery("pageNum", "1"))
	pageSize, _ := strconv.Atoi(c.DefaultQuery("pageSize", "9"))
	offset := (pageNum - 1) * pageSize

	query := `
		SELECT w.id, w.classid, wc.name as classname, w.description, w.small_picurl, 
		       w.score, w.nickname, w.create_time,
		       GROUP_CONCAT(wt.tag_name ORDER BY wt.tag_name SEPARATOR ',') as tags,
		       COALESCE(us.user_score, '0') as user_score
		FROM wallpaper w
		LEFT JOIN wallpaper_classify wc ON w.classid = wc.id
		LEFT JOIN wallpaper_tag wt ON w.id = wt.wallpaper_id
		LEFT JOIN user_score us ON w.id = us.wallpaper_id AND us.access_key = ?
		WHERE w.checked = 1
		GROUP BY w.id, w.classid, wc.name, w.description, w.small_picurl, w.score, w.nickname, w.create_time, us.user_score
		ORDER BY w.create_time DESC
		LIMIT ? OFFSET ?
	`

	rows, err := database.DB.Query(query, accessKey, pageSize, offset)
	if err != nil {
		c.JSON(http.StatusOK, models.Response{
			ErrCode:  400,
			ErrMsg:   "查询失败",
			Data:     nil,
			TimeCost: time.Since(startTime).Milliseconds(),
		})
		return
	}
	defer rows.Close()

	var wallpapers []models.Wallpaper
	for rows.Next() {
		var wallpaper models.Wallpaper
		var tabsStr sql.NullString
		var score sql.NullFloat64
		var userScore sql.NullString

		err := rows.Scan(&wallpaper.ID, &wallpaper.ClassID, &wallpaper.ClassName, &wallpaper.Description, &wallpaper.SmallPicURL, &score, &wallpaper.Nickname, &wallpaper.CreateTime, &tabsStr, &userScore)
		if err != nil {
			continue
		}

		if score.Valid {
			wallpaper.Score = utils.FormatFloat(score.Float64)
		} else {
			wallpaper.Score = "0"
		}

		if userScore.Valid {
			wallpaper.UserScore = userScore.String
		}

		if tabsStr.Valid {
			wallpaper.Tabs = utils.ParseTabsString(tabsStr.String)
		} else {
			wallpaper.Tabs = []string{}
		}

		wallpapers = append(wallpapers, wallpaper)
	}

	// 获取总数
	var total int
	countQuery := "SELECT COUNT(*) FROM wallpaper WHERE checked = 1"
	database.DB.QueryRow(countQuery).Scan(&total)

	c.JSON(http.StatusOK, models.Response{
		ErrCode:  0,
		ErrMsg:   "查询成功",
		Data:     wallpapers,
		Total:    &total,
		TimeCost: time.Since(startTime).Milliseconds(),
	})
}

// SearchWall 搜索壁纸
func SearchWall(c *gin.Context) {
	startTime := time.Now()

	keyword := c.Query("keyword")
	if keyword == "" {
		c.JSON(http.StatusOK, models.Response{
			ErrCode:  400,
			ErrMsg:   "搜索关键字不能为空",
			Data:     nil,
			TimeCost: time.Since(startTime).Milliseconds(),
		})
		return
	}

	pageNum, _ := strconv.Atoi(c.DefaultQuery("pageNum", "1"))
	pageSize, _ := strconv.Atoi(c.DefaultQuery("pageSize", "9"))
	offset := (pageNum - 1) * pageSize

	// 使用全文搜索或LIKE查询
	query := `
		SELECT w.id, w.classid, w.description, w.small_picurl, w.score, w.nickname,
		       GROUP_CONCAT(wt.tag_name ORDER BY wt.tag_name SEPARATOR ',') as tags
		FROM wallpaper w
		LEFT JOIN wallpaper_tag wt ON w.id = wt.wallpaper_id
		WHERE w.checked = 1 AND (w.description LIKE ? OR wt.tag_name LIKE ?)
		GROUP BY w.id, w.classid, w.description, w.small_picurl, w.score, w.nickname
		ORDER BY w.create_time DESC
		LIMIT ? OFFSET ?
	`

	keywordPattern := "%" + keyword + "%"
	rows, err := database.DB.Query(query, keywordPattern, keywordPattern, pageSize, offset)
	if err != nil {
		c.JSON(http.StatusOK, models.Response{
			ErrCode:  400,
			ErrMsg:   "查询失败",
			Data:     nil,
			TimeCost: time.Since(startTime).Milliseconds(),
		})
		return
	}
	defer rows.Close()

	var wallpapers []models.Wallpaper
	for rows.Next() {
		var wallpaper models.Wallpaper
		var tabsStr sql.NullString
		var score sql.NullFloat64

		err := rows.Scan(&wallpaper.ID, &wallpaper.ClassID, &wallpaper.Description, &wallpaper.SmallPicURL, &score, &wallpaper.Nickname, &tabsStr)
		if err != nil {
			continue
		}

		if score.Valid {
			wallpaper.Score = utils.FormatFloat(score.Float64)
		} else {
			wallpaper.Score = "0"
		}

		if tabsStr.Valid {
			wallpaper.Tabs = utils.ParseTabsString(tabsStr.String)
		} else {
			wallpaper.Tabs = []string{}
		}

		wallpapers = append(wallpapers, wallpaper)
	}

	// 获取总数
	var total int
	countQuery := `
		SELECT COUNT(DISTINCT w.id)
		FROM wallpaper w
		LEFT JOIN wallpaper_tag wt ON w.id = wt.wallpaper_id
		WHERE w.checked = 1 AND (w.description LIKE ? OR wt.tag_name LIKE ?)
	`
	database.DB.QueryRow(countQuery, keywordPattern, keywordPattern).Scan(&total)

	c.JSON(http.StatusOK, models.Response{
		ErrCode:  0,
		ErrMsg:   "查询成功",
		Data:     wallpapers,
		Total:    &total,
		TimeCost: time.Since(startTime).Milliseconds(),
	})
}
